package
{
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.*;
	import flash.text.*;
	
	/** Displays set of tools that user may select to act upon drawing panel */
	public class ShapeSelectionMenu extends Sprite
	{
		// constants
		private static const X_PADDING:int = 4, Y_PADDING:int = 4;
		private static const DEFAULT_TEXT_COLOR:uint = 0x4444AA;
		private static const TOOL_OUTLINE_COLOR:uint = 0x000000;
		public var WIDTH:int = 192; // 4 + 90 + 4 + 90 + 4
		public var HEIGHT:int = 46;
		public var TITLE_HEIGHT:int = 46;
		public var TYPES:Array;
		// private objects
		private var parentPolygons:Array;
		// buttons
		private var toolBack:Sprite, gameBack:Sprite, parentBoard:Sprite; 
		private var selectedButton:Sprite, parentPolygonArea:Sprite;
		private var selectedOutline:Shape, overOutline:Shape;
		private var loadedParentPolygon:ParentPolygon; // if a shape is in on the board use this reference
		private var targets:Array, hiddenTargets:Array;
		private var _disabled:Boolean=false;
		// textfields
		private var toolTField:TextField,gameTField:TextField, messageTField:TextField, parentTitleTField:TextField; 
		private var shapeType:String;
		
		/// getters setters
		public function get disabled():Boolean{return _disabled;}
		public function set disable(b:Boolean):void{_disabled=b;}
		
		public function ShapeSelectionMenu(WIDTH:Number, HEIGHT:Number, parentPolygons:Array, TYPES:Array)
		{
			this.WIDTH = WIDTH;
			this.HEIGHT = HEIGHT;
			this.TITLE_HEIGHT = HEIGHT/15; 
			this.TYPES = TYPES;
			this.parentPolygons = parentPolygons			
			
			gameBack = new Sprite();
			gameBack.graphics.lineStyle(1,0x000000);
			gameBack.graphics.beginFill(0x6666AA);
			gameBack.graphics.drawRect(0,0,WIDTH, TITLE_HEIGHT);
			gameBack.graphics.endFill();
			this.addChild(gameBack);
			
			gameTField = new TextField ();
			gameTField.mouseEnabled = false;
			gameTField.selectable = false;
			gameTField.defaultTextFormat = new TextFormat ("arial", 22, 0xFFFFFF, null, null, null, null, null, "center");
			gameTField.text = "Shapes";
			gameTField.autoSize = "center";
			gameTField.width = WIDTH/2;
			gameTField.x = WIDTH/2+10;
			gameTField.y = 0;
			gameBack.addChild(gameTField);
			
			// title background
			toolBack = new Sprite();
			toolBack.graphics.lineStyle(1,0x000000);
			toolBack.graphics.beginFill(0xCC6666);
			toolBack.graphics.drawRect(0,0,WIDTH/2, TITLE_HEIGHT*2/3);
			toolBack.graphics.endFill();
			toolBack.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOverTool);
			toolBack.x = 0;
			this.addChild(toolBack);
			
			// draw title
			toolTField = new TextField ();
			toolTField.mouseEnabled = false;
			toolTField.selectable = false;
			toolTField.defaultTextFormat = new TextFormat ("arial", 22, 0xAAAAAA, null, null, null, null, null, "center");
			toolTField.text = "Tools";
			toolTField.autoSize = "center";
			toolTField.width = WIDTH/2;
			toolTField.x = 10;
			toolTField.y = 0;
			toolBack.addChild(toolTField);			
			
			// draw message board
			drawParentBoard();
			parentBoard.x = (this.width - parentBoard.width)/2;
			parentBoard.y = gameBack.y + gameBack.height + Y_PADDING;
			this.addChild(parentBoard);
			
			// draw target buttons
			targets = new Array();
			hiddenTargets = new Array();
			
			this.addEventListener(Event.ADDED, handleAdded);
		}
		private function handleAdded(event:Event):void
		{
			this.removeEventListener(Event.ADDED, handleAdded);
			// draw some background color
			this.graphics.lineStyle(1, 0x444444);
			this.graphics.beginFill(0xEEFFEE);
			this.graphics.drawRect(0,0,WIDTH, HEIGHT);
			this.graphics.endFill();
			drawTargets();
			// begin with top target selected
			if (targets != null && targets.length > 0)
			{
				this.drawOverButton(targets[0]);
				this.selectButton(targets[0]);
			}
			this.addEventListener(Event.REMOVED, handleRemoved);
			
		}
		private function drawTargets():void
		{
			var cury:Number = parentBoard.y + parentBoard.height + Y_PADDING;
			for (var i:int=0; i < parentPolygons.length; i++)
			{
				var target:Sprite = drawTargetButton(i, parentPolygons[i]);
				if (target != null)
				{
					target.y = cury;
					target.x = (WIDTH - target.width)/2;					
					cury = target.y + target.height + Y_PADDING;
				}
			}			
		}
		/******************* INTERACTIVITY **************************/
		
		/** handle mouse over a shape name */
		private function handleOverButton (event:MouseEvent):void
		{
			drawOverButton(Sprite(event.currentTarget));	
		}
		private function drawOverButton (sprite:Sprite):void
		{
			if (!disabled)
			{
				if (overOutline == null || loadedParentPolygon == null || parentTitleTField.text != sprite.name.split("_").join(" "))
				{
					// create outline if not made yet
					if (overOutline == null)
					{
						overOutline = new Shape();
						this.addChild(overOutline);
					} else
					{
						overOutline.graphics.clear();
					}	
					// clear previously loaded
					if (loadedParentPolygon != null)
					{
						parentPolygonArea.removeChild(loadedParentPolygon);
						parentTitleTField.text = "Choose a shape.";
						loadedParentPolygon = null;
					}
					// draw parent in parentboard
					for each (var pshape:ParentPolygon in parentPolygons)
					{
						if (pshape.type == sprite.name)
						{
							break;
						}
					}
					// DEAL WITH TITLE
					parentTitleTField.text = pshape.type.split("_").join(" ");
					var minProp:Number = Math.min(parentPolygonArea.width/pshape.WIDTH, parentPolygonArea.height / pshape.HEIGHT);
					pshape.scale = minProp;
					parentPolygonArea.addChild(pshape);
					loadedParentPolygon = pshape;
					
					overOutline.graphics.lineStyle(4,0x000000);
					overOutline.graphics.drawRect(0, 0,sprite.width, sprite.height);
					overOutline.graphics.lineStyle(2,0xFFFFFF);
					overOutline.graphics.drawRect(0, 0, sprite.width, sprite.height);
					
					overOutline.x = sprite.x;
					overOutline.y = sprite.y;
					// add a click handler
					sprite.addEventListener (MouseEvent.CLICK, handleClickButton);
				}
			}
		}
		/** If the clicked button is already selected, unselect, if it is not select */
		private function handleClickButton (event:MouseEvent):void
		{
			if (!disabled)
			{
				if (selectedButton != event.currentTarget)
				{				
					selectButton(Sprite(event.currentTarget));
				} else 
				{
					//unselectButton();
				}
			}
		}
		private function selectButton(target:Sprite):void
		{
			if (!disabled)
			{
				if (selectedOutline == null)
				{
					drawSelectedOutline(target.width, target.height);
				}
				// update references
				selectedOutline.x = target.x;
				selectedOutline.y = target.y;
				selectedButton = target;
				if (overOutline != null)
				{
					overOutline.x = selectedButton.x;
					overOutline.y = selectedButton.y;
				}
				shapeType = selectedButton.name;
				// call to parent function
				GeometryGameItem(parent).processCommand("shapeSelection", "in_progress", this, new Array(shapeType));
			}
		}
		/** Unselects currently selected */
		public function unselectButton():void
		{
			if (!disabled)
			{
				if (selectedOutline != null)
				{
					this.removeChild(selectedOutline);
					selectedOutline = null;
					selectedButton = null;
					shapeType = "";
					// call to parent function
					GeometryGameItem(parent).processCommand("shapeSelection","in_progress",this,new Array(shapeType));
				}
			}
		}
		/** Searches through target buttons for one that matches this type, then removes from display and places on hidden list */
		public function hideTargetType(type:String):Boolean
		{
			var found:Boolean = false;
			var prevY:Number, _prevY:Number;
			for (var i:uint=0; i < targets.length; i++)
			{
				var t:Sprite = targets[i];
				// has type been found yet?
				if (!found)
				{
					if (t.name == type)
					{
						unselectButton();
						hiddenTargets.push(targets.splice(i,1)[0]);
						prevY = t.y;
						this.removeChild(t);
						if (loadedParentPolygon != null && loadedParentPolygon.type == type)
						{
							parentPolygonArea.removeChild(loadedParentPolygon);
							parentTitleTField.text = "Choose a shape.";
							loadedParentPolygon = null;
						}
						if (targets != null && targets.length > 0) this.selectButton(targets[0]);
						found = true;
					}
				} else
				{ // already found, move the next target up
					_prevY = t.y;
					//t.y = prevY;
					prevY = _prevY;
				}
			}
			return found;
		}
		/** Searches through target buttons for one that matches this type, then removes from display and places on hidden list */
		public function showTargetType(type:String):Boolean
		{
			var found:Boolean = false;
			var prevY:Number, _prevY:Number;
			//trace("hiddentTargets length", hiddenTargets.length);
			for (var i:uint=0; i < hiddenTargets.length; i++)
			{
				var t:Sprite = hiddenTargets[i];
				// has type been found yet?
				if (!found)
				{
					if (t.name == type)
					{
						//unselectButton();
						t.addEventListener(MouseEvent.MOUSE_OVER, handleOverButton);
						targets.push(hiddenTargets.splice(i,1)[0]);
						prevY = t.y;
						this.addChild(t);
						found = true;
					}
				} else
				{ // already found, move the next target up
					_prevY = t.y;
					//t.y = prevY;
					prevY = _prevY;
				}
			}
			return found;
		}
		/** Adds any hidden targets back on the target list and displays */
		public function reset():void
		{
			_disabled = false;
			// remove targets off display list
			for each (var t:Sprite in targets){this.removeChild(t);}
			targets = new Array();
			hiddenTargets = new Array();
			drawTargets();
		}
		
		/****************** SETUP BUTTONS ***************************/
		/** The message board is a place for instructions to the user to be placed */
		private function drawParentBoard():void
		{
			if (parentBoard == null)
			{
				parentBoard = new Sprite();
				parentBoard.graphics.lineStyle(2,0x000000);
				parentBoard.graphics.beginFill(0x003300);
				parentBoard.graphics.drawRoundRect(0,0, WIDTH*3/4, WIDTH, 10);
				parentTitleTField = new TextField();
				parentTitleTField.defaultTextFormat = new TextFormat("arial", 18, 0xFFFFFF, null, null, null, null, null, "center");
				parentTitleTField.selectable = false;
				parentTitleTField.mouseEnabled = false;
				parentTitleTField.text = "Choose a shape.";
				parentTitleTField.width = parentBoard.width-4;
				parentTitleTField.height = parentBoard.width *1/3;
				parentTitleTField.wordWrap = true;
				parentTitleTField.x = (parentBoard.width - parentTitleTField.width)/2;
				parentBoard.addChild(parentTitleTField);
				parentPolygonArea = new Sprite();
				parentPolygonArea.graphics.lineStyle(1, 0xFFFFFF);
				parentPolygonArea.graphics.drawRect(0,0,parentBoard.width-10, parentBoard.height*2/3);
				parentPolygonArea.x = (parentBoard.width - parentPolygonArea.width)/2;
				parentPolygonArea.y = parentBoard.height - parentPolygonArea.height - Y_PADDING;
				parentBoard.addChild(parentPolygonArea);
				this.addChild(parentBoard);
			} else
			{
				messageTField.text = "";
			}
			
		}
		/** This function places a button that initiates the shape "growing" process */
		private function drawTargetButton(i:int, pp:ParentPolygon):Sprite
		{
			var type:String = pp.type;
			if (TYPES.indexOf(type) > -1)
			{
				// put the tfield on a sprite back
				var target:Sprite = new Sprite();
				target.graphics.lineStyle(1,0x333333);
				target.graphics.beginFill(0x666666);
				target.graphics.drawRect(0,0,(WIDTH-X_PADDING/2)*3/4, (WIDTH-X_PADDING/2)*1/4);
				target.graphics.endFill();
				target.name = type;				
				
				// Draw a textfield for the target
				var tfield:TextField = new TextField();
				tfield.mouseEnabled = false;
				tfield.selectable = false;
				tfield.defaultTextFormat = new TextFormat("arial", 18, 0xFFFFFF, null, null, null, null, null, "center");
				tfield.wordWrap = true;
				tfield.width = target.width-4;
				type = type.split("_").join(" ");
				tfield.autoSize = "center";
				tfield.text = type;				
				tfield.x = (target.width - tfield.width)/2;
				tfield.y = (target.height - tfield.height)/2;				
				target.addChild(tfield);
				if (!pp.used)
				{
					this.addChild(target);
					target.addEventListener(MouseEvent.MOUSE_OVER, handleOverButton);
					targets.push(target);	
				} else
				{
					hiddenTargets.push(target);
				}
				return target;
			}
			return null;
		}
		
		private function drawSelectedOutline(BUTTON_WIDTH:Number, BUTTON_HEIGHT:Number):void
		{
			if (selectedOutline == null)
			{
				selectedOutline = new Shape();
				this.addChild(selectedOutline);
			}
			//outside violet
			//selectedOutline.graphics.lineStyle(1,0x000000);
			selectedOutline.graphics.lineStyle(2,0xFF66DD);
			selectedOutline.graphics.drawRect(-2, -2, BUTTON_WIDTH+4, BUTTON_HEIGHT+4);
			// center yellow
			//selectedOutline.graphics.lineStyle(2,0xFFFF44);
			selectedOutline.graphics.lineStyle(2,0xFFFFFF);
			selectedOutline.graphics.drawRect(0, 0, BUTTON_WIDTH, BUTTON_HEIGHT);
			//inside black
			//selectedOutline.graphics.lineStyle(1,0x000000);
			selectedOutline.graphics.lineStyle(2,0xFF66DD);
			selectedOutline.graphics.drawRect(2, 2, BUTTON_WIDTH-4, BUTTON_HEIGHT-4);			
			
		}
		
		/////////// INTERACTIVITY WITH GAME MENU, COMPLETES THIS 
		/** Highlights game menu tab, then allows clicking */
		private function handleMouseOverTool(event:MouseEvent):void
		{			
			if (!disabled)
			{
				toolBack.removeEventListener(MouseEvent.MOUSE_OVER, handleMouseOverTool);
				toolBack.graphics.clear();
				toolBack.graphics.lineStyle(1,0x000000);
				toolBack.graphics.beginFill(0xCC6666);
				toolBack.graphics.drawRect(0,0,WIDTH/2, TITLE_HEIGHT*2/3);
				toolBack.graphics.endFill();
				toolTField.defaultTextFormat = new TextFormat ("arial", 22, 0xFFFFFF, null, null, null, null, null, "center");
				toolTField.text = "Tools";
				toolBack.addEventListener(MouseEvent.MOUSE_OUT, handleMouseOutTool);
				toolBack.addEventListener(MouseEvent.CLICK, handleMouseClickTool);
			}
		}
		/** Un-Highlights game menu tab, then dis-allows clicking */
		private function handleMouseOutTool(event:MouseEvent):void
		{
			if (!disabled)
			{
				toolBack.removeEventListener(MouseEvent.MOUSE_OUT, handleMouseOutTool);
				toolBack.removeEventListener(MouseEvent.CLICK, handleMouseClickTool);
				toolBack.graphics.clear();
				toolBack.graphics.lineStyle(1,0x000000);
				toolBack.graphics.beginFill(0xAA6666);
				toolBack.graphics.drawRect(0,0,WIDTH/2, TITLE_HEIGHT*2/3);
				toolBack.graphics.endFill();
				toolTField.defaultTextFormat = new TextFormat ("arial", 22, 0xAAAAAA, null, null, null, null, null, "center");
				toolTField.text = "Tools";
				toolBack.addEventListener(MouseEvent.MOUSE_OVER, handleMouseOverTool);
			}
			
		}
		/** Removes listeners and dispatches a COMPLETE event */
		private function handleMouseClickTool(event:MouseEvent):void
		{
			if (!disabled)
			{
				GeometryGameItem(parent).processCommand("shapeSelectionMenu", "complete", this);		
			}
			
		}
		private function handleRemoved(event:Event):void
		{
			if (!disabled)
			{
				this.removeEventListener(Event.REMOVED, handleRemoved);
				toolBack.removeEventListener(MouseEvent.MOUSE_OUT, handleMouseOutTool);
				toolBack.removeEventListener(MouseEvent.CLICK, handleMouseClickTool);
			}
		}
	}
}